package com.xjgc.server;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xjgc.msibase.entity.MsiExoSystemServer;
import com.xjgc.msibase.entity.MsiServerRecord;
import com.xjgc.msibase.entity.MsiServerRecordInfo;
import com.xjgc.msibase.service.IMsiServerRecordInfoService;
import com.xjgc.msibase.service.IMsiServerRecordService;
import com.xjgc.msibase.service.IMsiServerTaskService;
import com.xjgc.msibase.vo.MsiServerTaskExoServer;
import com.xjgc.rest.ExoRestServerCall;
import com.xjgc.rest.JsonUtils;
import com.xjgc.rest.ao.MsiRealAO;
import com.xjgc.webservice.ExoWebServiceCall;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;
import org.apache.cxf.transport.http.HTTPConduit;
import org.jeecg.common.api.vo.Result;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Date;
import java.util.Map;

/**
 * @author: 小逗号
 * @date: 2023-11-28
 * @description:
 * @since:
 */
@Slf4j
@Component
public class MsiRealHandle {

    @Resource
    private IMsiServerTaskService msiServerTaskService;
    @Resource
    private IMsiServerRecordService msiServerRecordService;
    @Resource
    private IMsiServerRecordInfoService msiServerRecordInfoService;
    @Resource
    private ExoRestServerCall exoRestServerCall;
    @Resource
    private ExoWebServiceCall exoWebServiceCall;

    public Result<?> handle(MsiRealAO msiRealAO) {
        return this.handle(msiRealAO.getServerCode(), msiRealAO.getTaskCode(), msiRealAO.getParams());
    }

    /**
     * @param serverCode
     * @param taskCode
     * @param param
     * @return
     */
    public Result<?> handle(String serverCode, String taskCode, Map<String, Object> param) {
        log.info("中间库Rest实时接口:服务名{}-任务名{}", serverCode, taskCode);
        //1.校验通用参数
        StringBuffer errorMsg = new StringBuffer();
        if (!param.containsKey("orgCode")) {
            errorMsg.append("单位代码[orgCode]不能为空!");
        }
        if (!param.containsKey("sourceSystem")) {
            errorMsg.append("发起系统[sourceSystem]不能为空!");
        }
        if (!param.containsKey("serialNo")) {
            errorMsg.append("流水号[serialNo]不能为空!");
        }
        if (StringUtils.isNotBlank(errorMsg)) {
            return Result.error(errorMsg.toString());
        }
        if (param.size() == 3) {
            return Result.error("缺少参数!");
        }

        //2.查询中间库任务配置
        MsiServerTaskExoServer taskExoServer = msiServerTaskService.getTaskExoServer(serverCode, taskCode);
        if (taskExoServer == null) {
            log.error("{}-{}中间库任务未上线!", serverCode, taskCode);
            return Result.error("中间库任务未上线!");
        }
        //3.查询流水号是否已处理
        String orgCode = param.get("orgCode").toString();
        String sourceSystem = param.get("sourceSystem").toString();
        String serialNo = param.get("serialNo").toString();
        MsiServerRecord msiServerRecord = new MsiServerRecord(serverCode, taskCode, serialNo, sourceSystem);
        MsiServerRecord oldRecord = msiServerRecordService.getRecord(msiServerRecord);
        if (oldRecord != null) {
            String responseText = oldRecord.getResponseText();
            if (StringUtils.isNotBlank(responseText)) {
                log.warn("流水号[{}]任务已处理,直接返回处理结果!", serialNo);
                JSONObject jsonObject = JSONObject.parseObject(responseText);
                Result result = JSON.toJavaObject(jsonObject, Result.class);
                return result;
            } else {
                log.warn("流水号[{}]任务处理中!", serialNo);
                return Result.error(serialNo + "任务已经在处理中!请勿重复提交");
            }
        }
        //新的任务流水号,保存请求
        log.info("新的任务流水号==>{}", serialNo);
        String requestText = JSON.toJSONString(param);
        log.info("保存,请求参数==>{}", requestText);
        msiServerRecordService.addRecord(msiServerRecord, requestText);
        log.info("任务处理.....");
        Result result = handle(taskExoServer, msiServerRecord);


        String responseText = JSON.toJSONString(result);
        log.info("保存,响应参数==>{}", responseText);
        msiServerRecordService.updateResponse(msiServerRecord, responseText);
        return result;


    }

    private Result handle(MsiServerTaskExoServer task, MsiServerRecord record) {

        //分发任务调用WebService服务
        if (MsiExoSystemServer.WEBSERVICE.equals(task.getExoServerType())) {
            return this.zfWs(task, record);
        } else if (MsiExoSystemServer.REST.equals(task.getExoServerType())) {
            //分发任务调用Rest服务
            Result result = this.zfRest(task, record);
            return result;
        } else {
            return Result.error("分发任务配置错误!");
        }
    }

    /**
     * 转发WS
     *
     * @param task
     * @param record
     * @return
     */
    private Result zfWs(MsiServerTaskExoServer task, MsiServerRecord record) {
        //1.动态代理 or  客户端
        //1.1 动态代理 取wsdl
//        JaxWsClientProxy.getClient()
//        JaxWsDynamicClientFactory jaxWsDynamicClientFactory = JaxWsDynamicClientFactory.newInstance();
//        try {
//            Client client = jaxWsDynamicClientFactory.createClient("http://10.10.6.27:8080/MsiWebServer/ws/SapToMsiReal?wsdl");
//            HTTPConduit conduit = (HTTPConduit) client.getConduit();
////            conduit.setClient();
//            Object[] results = client.invoke(wsMethod, wsTask, serialNo, xml, sys);
//            Object result = results[0];
//            System.out.println(result.toString());
       //1.2  客户端




        //解析JSON,转XML
        String paramClass = task.getParamClass();
        String requestXml = JsonUtils.toXml(record, paramClass);
        //WebService服务名
        String webService = task.getWebService();
        String wsTask = StringUtils.isBlank(task.getConstant()) ? webService : webService + "[" + task.getConstant() + "]";
        log.info("WebService分发任务==>[{}]", wsTask);
        msiServerRecordInfoService.add(record.getId(), new Date(), MsiServerRecordInfo.Node.ZF_WS, wsTask, requestXml);
        try {
            String response = exoWebServiceCall.call(webService, task.getConstant(), "MSI" + System.currentTimeMillis(), requestXml);
            //String response = ExoWebServiceUtils.call(webService, task.getConstant(), "MSI" + System.currentTimeMillis(), requestXml);
            msiServerRecordInfoService.add(record.getId(), new Date(), MsiServerRecordInfo.Node.ZF_WS_RES, wsTask, response);
            return Result.OK(response);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("转发WebService失败,", e);
            msiServerRecordInfoService.add(record.getId(), new Date(), MsiServerRecordInfo.Node.ZF_WS_RES, "转发WebService失败," + e.getMessage(), null);
            return Result.error("转发WebService失败!");
        }
    }

    /**
     * 转发Rest
     *
     * @param task
     * @param record
     * @return
     */
    private Result zfRest(MsiServerTaskExoServer task, MsiServerRecord record) {
        String requestJson = record.getRequestText();
        JSONObject json = JSONObject.parseObject(requestJson);
        Result result = exoRestServerCall.requestExoServer(record.getId(), task, json);
        return result;
        /*String paramClass = task.getParamClass();
        //解XML,并提取JSON
        XParam xParam = null;
        try {
            xParam = XmlUtils.fromXml(record, paramClass, requestXml);
            msiServerRecordInfoService.add(record.getId(), new Date(), MsiServerRecordInfo.Node.PARSE_XML);
        } catch (Exception e) {
            msiServerRecordInfoService.add(record.getId(), new Date(), MsiServerRecordInfo.Node.PARSE_XML, "xml解析失败!");
            log.error(record.getId() + "xml解析失败!", e);
            return Result.error("xml解析失败!");
        }
        JSON json = xParam.dataAsJson();
        msiServerRecordInfoService.add(record.getId(), new Date(), MsiServerRecordInfo.Node.TO_JSON);
        log.info("提取dataAsJson ==> {}", json);
        Result result = exoRestServerCall.requestExoServer(record.getId(), task, json);
        return result;*/
    }

}
